﻿using BOSTools.DirectoryManifestGenerator;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
namespace DirectoryManifestTest
{
    
    
    /// <summary>
    ///This is a test class for FileDetailReaderTest and is intended
    ///to contain all FileDetailReaderTest Unit Tests
    ///</summary>
    [TestClass()]
    public class FileDetailReaderTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void FileDetailReaderConstructor_NullTest()
        {
            FileDetailReader reader = new FileDetailReader(null);
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void FileDetailReaderConstructor_EmptyStringTest()
        {
            FileDetailReader reader = new FileDetailReader(String.Empty);
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void FileDetailReaderConstructor_InvalidDirTest()
        {
            string sourceDir = @"l:\asdfasfd";

            Assert.IsFalse(Directory.Exists(sourceDir), "Directory {0} exists but shouldn't", sourceDir);
            FileDetailReader reader = new FileDetailReader(sourceDir);
        }

        [TestMethod()]
        public void FileDetailReaderConstructor_ValidDirTest()
        {
            string sourceDir = TestContext.TestDir;
            Assert.IsTrue(Directory.Exists( sourceDir ));
            FileDetailReader reader = new FileDetailReader(sourceDir);
        }

        [TestMethod()]
        public void FileDetailReader_GetFileDetailTest()
        {
            string file = Path.Combine(TestContext.TestDeploymentDir, "10bytes.txt");
            Assert.IsTrue(File.Exists(file), "Deployment file {0} not found", file);

            FileDetailReader reader = new FileDetailReader(TestContext.TestDeploymentDir);
            FileDetail detail = reader.GetFileDetailForFile(file);

            Assert.AreEqual("10bytes.txt", detail.FileName, true);
            Assert.AreEqual("10bytes.txt", detail.RelativeFileName, true);
            Assert.AreEqual(10, detail.FileLengthBytes);
            Assert.AreNotEqual(new DateTime(), detail.DateCreated);
            Assert.AreNotEqual(detail.DateModified, detail.DateCreated);
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void FileDetailReader_GetFileDetail_EmptyString()
        {
            FileDetailReader reader = new FileDetailReader(TestContext.TestDeploymentDir);
            reader.GetFileDetailForFile(String.Empty);
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void FileDetailReader_GetFileDetail_NullString()
        {
            FileDetailReader reader = new FileDetailReader(TestContext.TestDeploymentDir);
            reader.GetFileDetailForFile(null);
        }

        [TestMethod()]
        public void FileDetailReader_GetFileDetail_NonexistentFile()
        {
            string file = @"l:\asdasdad.ddd";
            Assert.IsFalse( File.Exists( file ), "File exists that shouldn't" );

            FileDetailReader reader = new FileDetailReader(TestContext.TestDeploymentDir);
            Assert.IsNull( reader.GetFileDetailForFile(file), "Non-null result for nonexistent file" );
        }

        [TestMethod()]
        public void FileDetailReader_GetFileDetail_VersionCheck()
        {
            string file = Path.Combine(TestContext.TestDeploymentDir, "StaticVersionAssembly.dll");
            Assert.IsTrue(File.Exists(file), "Couldn't find test file {0}", file);

            FileDetailReader reader = new FileDetailReader(TestContext.TestDeploymentDir);
            FileDetail detail = reader.GetFileDetailForFile(file);
            Assert.IsNotNull(detail);

            Assert.IsNotNull(detail.FileVersion);
            Assert.IsNotNull(detail.ProductVersion);

            Assert.AreEqual(5, detail.FileVersion.MajorVersion);
            Assert.AreEqual(6, detail.FileVersion.MinorVersion);
            Assert.AreEqual(7, detail.FileVersion.BuildNumber);
            Assert.AreEqual(8, detail.FileVersion.RevisionNumber);

            Assert.AreEqual(5, detail.ProductVersion.MajorVersion);
            Assert.AreEqual(6, detail.ProductVersion.MinorVersion);
            Assert.AreEqual(7, detail.ProductVersion.BuildNumber);
            Assert.AreEqual(8, detail.ProductVersion.RevisionNumber);
        }

        [TestMethod]
        public void GetNextFile_EmptyDir()
        {
            string sourceDir = Path.Combine(TestContext.TestDeploymentDir, "GetNextFile_EmptyDir");
            Directory.CreateDirectory(sourceDir);

            FileDetailReader reader = new FileDetailReader(sourceDir);
            Assert.IsNull( reader.GetNextFile(), "Empty directory returned non-null FileDetail" );
        }

        [TestMethod]
        public void GetNextFile_TwoFilesNoSubdirs()
        {
            string sourceDir = Path.Combine(TestContext.TestDeploymentDir, "GetNextFile_TwoFilesNoSubdirs");

            string [] paths = new string[]
            {
                "1.txt",
                "2.txt"
            };
            
            Directory.CreateDirectory(sourceDir);

            foreach (string path in paths)
            {
                TestHelper.WriteText(Path.Combine(sourceDir, path), path);
            }


            FileDetailReader reader = new FileDetailReader(sourceDir);
            Assert.AreEqual(paths[0], reader.GetNextFile().RelativeFileName, false);
            Assert.AreEqual(paths[1], reader.GetNextFile().RelativeFileName, false);
            Assert.IsNull(reader.GetNextFile());
            Assert.IsNull(reader.GetNextFile());
        }

        [TestMethod]
        public void GetNextFile_OneFileInTwoSubdirs()
        {
            string sourceDir = Path.Combine(TestContext.TestDeploymentDir, "GetNextFile_OneFileInTwoSubdirs");

            string[] paths = new string[]
            {
                "0.txt",
                @"1\1.txt",
                @"2\2.txt"
            };

            Directory.CreateDirectory(sourceDir);
            Directory.CreateDirectory(Path.Combine(sourceDir, "1"));
            Directory.CreateDirectory(Path.Combine(sourceDir, "2"));

            foreach (string path in paths)
            {
                TestHelper.WriteText(Path.Combine(sourceDir, path), path);
            }


            FileDetailReader reader = new FileDetailReader(sourceDir);
            FileDetail detail = reader.GetNextFile();
            Assert.AreEqual(paths[0], detail.RelativeFileName, false);
            Assert.AreEqual("", detail.RelativeDirectory, false);

            Assert.AreEqual(paths[1], reader.GetNextFile().RelativeFileName, false);
            Assert.AreEqual(paths[2], reader.GetNextFile().RelativeFileName, false);
            Assert.IsNull(reader.GetNextFile());
        }
    }
}
